package com.hdu.dwh.controller;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.HashSet;
import java.util.Arrays;

import com.hdu.dwh.utils.AppJwtUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hdu.dwh.results.ResponseResult;
import com.hdu.dwh.annotation.RequirePermission;

@Component
public class LoginInterceptor implements HandlerInterceptor {

    // 从配置文件中读取身份验证开关
    @Value("${auth.enabled:true}")
    private boolean authEnabled;

    /**
     * 请求处理前进行拦截
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        // 如果身份验证未启用，则直接放行
        if (!authEnabled) {
            // 设置默认用户信息，便于调试
            request.setAttribute("currentUserId", "debug_user");
            request.setAttribute("currentUsername", "debug_user");
            request.setAttribute("currentUserType", "admin");
            return true;
        }

        // 获取 token 或 session
        String token = request.getHeader("Authorization"); // 示例使用 Authorization header

        if (token == null || !isValidToken(token)) {
            // 返回未登录错误
            Map<String, Object> data = new HashMap<>();
            data.put("code", 401);
            data.put("message", "未登录");
            String json = new ObjectMapper().writeValueAsString(ResponseResult.fail(data));
            response.setContentType("application/json;charset=utf-8");
            response.getWriter().write(json);
            return false; // 拦截请求
        }

        // 检查权限
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            RequirePermission requirePermission = handlerMethod.getMethodAnnotation(RequirePermission.class);

            if (requirePermission != null) {
                String[] requiredPermissions = requirePermission.value();
                String userType = AppJwtUtil.parseUserType(token);

                // 检查用户是否有权限访问该接口
                if (!hasPermission(userType, requiredPermissions)) {
                    Map<String, Object> data = new HashMap<>();
                    data.put("code", 403);
                    data.put("message", "权限不足，当前用户类型无法访问该接口");
                    String json = new ObjectMapper().writeValueAsString(ResponseResult.fail(data));
                    response.setContentType("application/json;charset=utf-8");
                    response.getWriter().write(json);
                    return false;
                }
            }


        }

        // 校验通过后，解析用户信息
        String userId = AppJwtUtil.parseUserId(token);
        String username = AppJwtUtil.parseUsername(token);
        String userType = AppJwtUtil.parseUserType(token);

        // 保存到 request，方便后面 Controller/Service 使用
        request.setAttribute("currentUserId", userId);
        request.setAttribute("currentUsername", username);
        request.setAttribute("currentUserType", userType);

        return true; // 放行
    }

    /**
     * 验证 token 是否有效
     */
    private boolean isValidToken(String token) {
        return AppJwtUtil.validateToken(token);
    }

    /**
     * 检查用户是否有权限访问接口
     * @param userType 用户类型
     * @param requiredPermissions 接口所需权限
     * @return 是否有权限
     */
    private boolean hasPermission(String userType, String[] requiredPermissions) {
        // 如果没有设置权限要求，则允许访问
        if (requiredPermissions == null || requiredPermissions.length == 0) {
            return true;
        }

        // 定义不同用户类型对应的权限
        Map<String, Set<String>> userPermissions = getUserPermissions();

        // 获取用户拥有的权限
        Set<String> userPerms = userPermissions.getOrDefault(userType, new HashSet<>());

        // 检查是否拥有任意一个所需权限（OR逻辑）
        for (String requiredPerm : requiredPermissions) {
            if (userPerms.contains(requiredPerm) || "admin".equals(userType)) {
                return true; // 管理员拥有所有权限
            }
        }

        return false;
    }

    /**
     * 获取用户类型对应的权限映射
     * @return 权限映射表
     */
    private Map<String, Set<String>> getUserPermissions() {
        Map<String, Set<String>> permissions = new HashMap<>();

        // 目前不同用户权限 " "内的只是示例，实际开发中请根据实际需求进行修改


        // 管理员权限
        Set<String> adminPerms = new HashSet<>(Arrays.asList(
                "user.manage",
                "data.analyze",
                "model.create",
                "model.edit",
                "model.delete",
                "system.config",
                "report.view",
                "dashboard.access"
        ));
        permissions.put("admin", adminPerms);

        // 数据分析师权限
        Set<String> analystPerms = new HashSet<>(Arrays.asList(
                "data.analyze",
                "report.view",
                "dashboard.access",
                "model.create"
        ));
        permissions.put("analyst", analystPerms);

        // 普通用户权限
        Set<String> userPerms = new HashSet<>(Arrays.asList(
                "report.view",
                "dashboard.access"
        ));
        permissions.put("user", userPerms);

        // 开发者权限
        Set<String> developerPerms = new HashSet<>(Arrays.asList(
                "data.analyze",
                "model.create",
                "model.edit",
                "report.view",
                "dashboard.access",
                "api.debulingma:rO0ABXNyAD1jb20uYWxpYmFiYWNsb3VkLmludGVsbGlqLmNvc3kudWkuc2VhcmNoLm1vZGVsLkNoYXRDb250ZXh0VGFnQrXDUxBKo3UCAA5MAA1jb21wb25lbnRUeXBldAASTGphdmEvbGFuZy9TdHJpbmc7TAAPY29udGV4dFByb3ZpZGVydAA+TGNvbS9hbGliYWJhY2xvdWQvaW50ZWxsaWovY29zeS91aS9zZWFyY2gvbW9kZWwvU3VnZ2VzdFByb21wdDtMAAdlbmRMaW5ldAATTGphdmEvbGFuZy9JbnRlZ2VyO0wABWV4dHJhdAAPTGphdmEvdXRpbC9NYXA7TAACaWRxAH4AAUwAB2xvYWRpbmd0AC1MamF2YS91dGlsL2NvbmN1cnJlbnQvYXRvbWljL0F0b21pY1JlZmVyZW5jZTtMAARuYW1lcQB+AAFMAAdwYXlsb2FkdAASTGphdmEvbGFuZy9PYmplY3Q7TAALcmVjb21tZW5kZWR0ABNMamF2YS9sYW5nL0Jvb2xlYW47TAAKc291cmNlVHlwZXEAfgABTAAIc3RhdExpbmVxAH4AA0wABHRleHRxAH4AAUwABHR5cGVxAH4AAUwABXZhbGlkcQB+AAd4cHQACGNvbWJvQm94c3IAPGNvbS5hbGliYWJhY2xvdWQuaW50ZWxsaWouY29zeS51aS5zZWFyY2gubW9kZWwuU3VnZ2VzdFByb21wdI78fI1Sv8N8AgAQWgAHZW5hYmxlZEwADWFjdGlvbkNvbW1hbmRxAH4AAUwADWNvbXBvbmVudFR5cGVxAH4AAUwAC2NvbnRleHROYW1lcQB+AAFMAA9jb250ZXh0UHJvdmlkZXJxAH4AAkwAD2RyaWxsRG93bkVuYWJsZXEAfgAHTAAFZXh0cmFxAH4ABEwABGhpbnRxAH4AAUwAAmlkcQB+AAFMAAhsaW5rVGV4dHEAfgABTAAQbmVlZENsZWFyQ29udGV4dHEAfgAHTAAUcmVxdWlyZWRDb250ZXh0SXRlbXN0ABBMamF2YS91dGlsL0xpc3Q7TAAYcmVxdWlyZWRDb250ZXh0UHJvdmlkZXJzcQB+AAtMAApzb3VyY2VUeXBlcQB+AAFMAAR0ZXh0cQB+AAFMAAR0eXBlcQB+AAF4cAFwdAAIY29tYm9Cb3h0AARmaWxlcHNyABFqYXZhLmxhbmcuQm9vbGVhbs0gcoDVnPruAgABWgAFdmFsdWV4cAFzcgARamF2YS51dGlsLkhhc2hNYXAFB9rBwxZg0QMAAkYACmxvYWRGYWN0b3JJAAl0aHJlc2hvbGR4cD9AAAAAAAAMdwgAAAAQAAAAAXQAC2NvbnRleHRUeXBlcQB+AA54dAAEZmlsZXQAJDdhMGMyNzkyLWIxZWQtNDllYy1hODJiLWQ5N2IxNmEyNDJiNHBwcHB0AAZzeXN0ZW10AAUjZmlsZXQAB2NvbnRleHRwc3EAfgARP0AAAAAAAAx3CAAAABAAAAACcQB+ABN0AARmaWxldAAIZmlsZVR5cGV0AARKQVZBeHQAcC9Vc2Vycy9zaGlrYWloYW8vSWRlYVByb2plY3RzL2RhdGEtd2FyZWhvdXNlL2R3aC1zZXJ2aWNlL3NyYy9tYWluL2phdmEvY29tL2hkdS9kd2gvY29udHJvbGxlci9DRENDb250cm9sbGVyLmphdmFzcgAramF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY1JlZmVyZW5jZeZXcdRVeFTGAgABTAAFdmFsdWVxAH4ABnhwcHEAfgAdcQB+AB1wcHB0ABJDRENDb250cm9sbGVyLmphdmFxAH4AGnA=g"
        ));
        permissions.put("developer", developerPerms);

        return permissions;
    }
}
